#include "linklist.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

/**
 * 功 能：
 *      创建一个链表
 * 参 数：
 *      无
 * 返回值：
 *      成功：操作句柄
 *      失败：NULL
 **/
Linklist *Linklist_create()
{
    TLinklist *ret = (TLinklist *)malloc(sizeof(TLinklist));
    if (ret == NULL)
        return NULL;
    memset(ret, 0, sizeof(TLinklist));
    // ret->length = 0;
    // ret->header.next = NULL;

    return ret;
}
/**
 * 功 能：
 *      销毁一个链表
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int LinkList_destory(Linklist **list)
{
    if (list != NULL)
    {
        free(*list);
        *list = NULL;
        return 0;
    }
    return -1;
}

/**
 * 功 能：
 *      清除一个链表, 使得链表恢复到初始状态
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int Linklist_clear(Linklist *list)
{
    TLinklist *tlist = NULL;
    if (list == NULL)
        return -1;
    tlist = (TLinklist *)list;
    tlist->length = 0;
    tlist->header.next = NULL;
    return 0;
}

/**
 * 功 能：
 *      获取链表长度
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：链表的长度
 *      失败：-1
 **/
int Linklist_Length(Linklist *list)
{
    TLinklist *tlist = NULL;
    if (list == NULL)
        return -1;
    tlist = (TLinklist *)list;
    return tlist->length;
}

/**
 * 功 能：
 *      在指定的位置插入一个元素
 * 参 数：
 *      list：要操作的链表
 *      node：要插入的节点
 *      pos ：要插入的位置
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int Linklist_insert(Linklist *list, LinkListNode *node, int pos)
{
    int i = 0;
    TLinklist *tlist = NULL;
    LinkListNode *current = NULL;
    if (list == NULL || node == NULL || pos < 0)
        return -1;

    tlist = (TLinklist *)list;
    if (pos > tlist->length)
        pos = tlist->length;

    current = &(tlist->header);

    while (i < pos && current->next != NULL)
    {
        i++;
        current = current->next;
    }
    // 让node链接后续的节点
    node->next = current->next;
    // 让前面的链表链接新的node节点
    current->next = node;
    // 让长度自加一
    tlist->length++;

    return 0;
}

/**
 * 功 能：
 *      获取指定位置的元素
 * 参 数：
 *      list：要操作的链表
 *      pos ：要获取元素的位置
 * 返回值：
 *      成功：节点的首地址
 *      失败：NULL
 **/
LinkListNode *Linklist_Get(Linklist *list, int pos)
{
    int i = 0;
    TLinklist *tlist = NULL;
    LinkListNode *current = NULL;
    if (pos < 0 || list == NULL)
        return NULL;
    tlist = (TLinklist *)list;
    if (pos > tlist->length)
        pos = tlist->length;
    // 让辅助指针变量指向链表的头部
    current = &(tlist->header);

    while (i < pos && current->next != NULL)
    {
        i++;
        current = current->next;
    }
    return current->next;
}

/**
 * 功 能：
 *      从指定的位置删除一个元素
 * 参 数：
 *      list：要操作的链表
 *      pos ：要删除元素的位置
 * 返回值：
 *      成功：删除节点的首地址
 *      失败：NULL
 **/
LinkListNode *Linklist_delete(Linklist *list, int pos)
{
    int i = 0;
    TLinklist *tlist = NULL;
    LinkListNode *current = NULL, *ret = NULL;

    if (list == NULL || pos < 0)
        return NULL;

    tlist = (TLinklist *)list;

    if (tlist->length < 1)
        return NULL;

    if (pos > tlist->length)
        pos = tlist->length;

    current = &(tlist->header);

    while (i < pos && current->next != NULL)
    {
        i++;
        current = current->next;
    }
    // 缓存被删除的节点位置
    ret = current->next;
    // 连线，跳过要删除的节点
    current->next = ret->next;
    // 长度自减一
    tlist->length--;

    return ret; //将删除的节点的地址返回，让调用者析构这个内存
}

func_linklist fun_linklist =
    {
        Linklist_create,
        LinkList_destory,
        Linklist_clear,
        Linklist_Length,
        Linklist_insert,
        Linklist_Get,
        Linklist_delete};
